﻿namespace Community.Ssis.RankTransformUi
{
    //using Conchango.SqlServer.SSIS.DataFlow.Properties;
    //using Conchango.SqlServer.SSIS.Design;
    using Microsoft.SqlServer.Dts.Design;
    using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
    using Microsoft.SqlServer.MessageBox;
    using System;
    using System.ComponentModel;
    using System.Drawing;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;

    public class RankTransformUIForm : Form
    {
        private IDTSComponentMetaData100 _componentMetadata;
        private CManagedComponentWrapper _designTimeComponent;
        private IErrorCollectionService _errorCollectionService;
        private IDTSInput100 _input;
        private IDTSOutput100 _output;
        private IDTSVirtualInput100 _virtualInput;
        private Button buttonCancel;
        private Button buttonOK;
        private CheckBox checkBoxDenseRank;
        private CheckBox checkBoxRank;
        private CheckBox checkBoxRowNumber;
        private DataGridViewCheckBoxColumn columnCheckBox;
        private DataGridViewCheckBoxColumn columnCheckBoxColumn;
        private DataGridViewCheckBoxColumn columnFunctionUsage;
        private DataGridViewTextBoxColumn columnName;
        private DataGridViewTextBoxColumn columnNameColumn;
        private DataGridViewTextBoxColumn columnSortKey;
        private DataGridViewTextBoxColumn columnSortKeyColumn;
        private IContainer components = null;
        private DataGridView dataGridViewColumns;
        private GroupBox groupBoxInputColumns;
        private GroupBox groupBoxOutputColumns;
        private Label labelDescription;
        public const string NameProperty = "Name";
        private TextBox textBoxDenseRank;
        private TextBox textBoxRank;
        private TextBox textBoxRowNumber;

        public RankTransformUIForm()
        {
            this.InitializeComponent();
        }

        private void CheckBoxCheckedChanged(object sender, EventArgs e)
        {
            var box = sender as CheckBox;
            if (box.Tag == null) return;
            var function = (RankTransformFunction)Enum.Parse(typeof(RankTransformFunction), box.Tag.ToString());
            var outputColumnTextBox = GetOutputColumnTextBox(function);
            outputColumnTextBox.Enabled = box.Checked;
            if (box.Checked)
            {
                if (outputColumnTextBox.Tag == null)
                {
                    var column = _designTimeComponent.InsertOutputColumnAt(_output.ID, _output.OutputColumnCollection.Count, function.ToString(), "");
                    _designTimeComponent.SetOutputColumnProperty(_output.ID, column.ID, "RankTransformFunction", function);
                    outputColumnTextBox.Text = function.ToString();
                    outputColumnTextBox.Tag = column.LineageID;
                    outputColumnTextBox.Enabled = true;
                }
            }
            else if (outputColumnTextBox.Tag != null)
            {
                _designTimeComponent.DeleteOutputColumn(_output.ID, Convert.ToInt32(outputColumnTextBox.Tag));
                outputColumnTextBox.Text = "";
                outputColumnTextBox.Tag = null;
                outputColumnTextBox.Enabled = false;
            }
        }

        private void dataGridViewColumns_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            var view = sender as DataGridView;
            if (e.RowIndex >= 0)
            {
                var cell = view.Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewCheckBoxCell;
                var selected = !Convert.ToBoolean(cell.Value);
                var cancel = false;
                var lineageId = Convert.ToInt32(view.Rows[e.RowIndex].Tag);
                switch (e.ColumnIndex)
                {
                    case 0:
                        OnColumnSelection(lineageId, selected, out cancel);
                        break;
                    case 3:
                        OnPartitionSelection(lineageId, selected, out cancel);
                        break;
                }
                if (cancel)
                {
                    view.CancelEdit();
                }
                else
                {
                    cell.Value = selected;
                }
            }
        }

        private void DetectOutputColumns()
        {
            var cos = _output.OutputColumnCollection;
            var num = cos.Count;
            for (var i = 0; i < num; i++)
            {
                var column = cos[i];
                var function = (RankTransformFunction)Enum.Parse(typeof(RankTransformFunction), column.CustomPropertyCollection[0].Value.ToString());
                var outputColumnTextBox = GetOutputColumnTextBox(function);
                outputColumnTextBox.Text = column.Name;
                outputColumnTextBox.Tag = column.LineageID;
                outputColumnTextBox.Enabled = true;
                GetOutputColumnCheckBox(function).Checked = true;
            }
        }

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        private CheckBox GetOutputColumnCheckBox(RankTransformFunction function)
        {
            switch (function)
            {
                case RankTransformFunction.Rank:
                    return checkBoxRank;

                case RankTransformFunction.DenseRank:
                    return checkBoxDenseRank;

                case RankTransformFunction.RowNumber:
                    return checkBoxRowNumber;
            }
            return null;
        }

        private TextBox GetOutputColumnTextBox(RankTransformFunction function)
        {
            switch (function)
            {
                case RankTransformFunction.Rank:
                    return textBoxRank;

                case RankTransformFunction.DenseRank:
                    return textBoxDenseRank;

                case RankTransformFunction.RowNumber:
                    return textBoxRowNumber;
            }
            return null;
        }

        internal void Initialize(IDTSComponentMetaData100 componentMetadata, IServiceProvider serviceProvider)
        {
            _componentMetadata = componentMetadata;
            _designTimeComponent = _componentMetadata.Instantiate();
            _errorCollectionService = serviceProvider.GetService(typeof(IErrorCollectionService)) as IErrorCollectionService;
            _input = _componentMetadata.InputCollection[0];
            _output = _componentMetadata.OutputCollection[0];
            SetInputVirtualInputColumns();
            DetectOutputColumns();
        }

        private void InitializeComponent()
        {
            System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
            this.dataGridViewColumns = new System.Windows.Forms.DataGridView();
            this.columnCheckBox = new System.Windows.Forms.DataGridViewCheckBoxColumn();
            this.columnSortKey = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.columnName = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.columnFunctionUsage = new System.Windows.Forms.DataGridViewCheckBoxColumn();
            this.checkBoxRank = new System.Windows.Forms.CheckBox();
            this.checkBoxDenseRank = new System.Windows.Forms.CheckBox();
            this.checkBoxRowNumber = new System.Windows.Forms.CheckBox();
            this.textBoxRank = new System.Windows.Forms.TextBox();
            this.textBoxDenseRank = new System.Windows.Forms.TextBox();
            this.textBoxRowNumber = new System.Windows.Forms.TextBox();
            this.groupBoxOutputColumns = new System.Windows.Forms.GroupBox();
            this.labelDescription = new System.Windows.Forms.Label();
            this.groupBoxInputColumns = new System.Windows.Forms.GroupBox();
            this.buttonOK = new System.Windows.Forms.Button();
            this.buttonCancel = new System.Windows.Forms.Button();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridViewColumns)).BeginInit();
            this.groupBoxOutputColumns.SuspendLayout();
            this.groupBoxInputColumns.SuspendLayout();
            this.SuspendLayout();
            // 
            // dataGridViewColumns
            // 
            this.dataGridViewColumns.AllowUserToAddRows = false;
            this.dataGridViewColumns.AllowUserToDeleteRows = false;
            dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Info;
            this.dataGridViewColumns.AlternatingRowsDefaultCellStyle = dataGridViewCellStyle1;
            this.dataGridViewColumns.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.dataGridViewColumns.BackgroundColor = System.Drawing.SystemColors.Window;
            this.dataGridViewColumns.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dataGridViewColumns.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
            this.columnCheckBox,
            this.columnSortKey,
            this.columnName,
            this.columnFunctionUsage});
            this.dataGridViewColumns.Location = new System.Drawing.Point(18, 28);
            this.dataGridViewColumns.Name = "dataGridViewColumns";
            this.dataGridViewColumns.RowHeadersVisible = false;
            this.dataGridViewColumns.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
            this.dataGridViewColumns.Size = new System.Drawing.Size(410, 127);
            this.dataGridViewColumns.TabIndex = 0;
            this.dataGridViewColumns.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridViewColumns_CellContentClick);
            // 
            // columnCheckBox
            // 
            this.columnCheckBox.HeaderText = "";
            this.columnCheckBox.Name = "columnCheckBox";
            this.columnCheckBox.Width = 40;
            // 
            // columnSortKey
            // 
            this.columnSortKey.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.ColumnHeader;
            this.columnSortKey.HeaderText = "Sort Key";
            this.columnSortKey.Name = "columnSortKey";
            this.columnSortKey.ReadOnly = true;
            this.columnSortKey.Width = 72;
            // 
            // columnName
            // 
            this.columnName.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
            this.columnName.HeaderText = "Name";
            this.columnName.Name = "columnName";
            this.columnName.ReadOnly = true;
            // 
            // columnFunctionUsage
            // 
            this.columnFunctionUsage.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.ColumnHeader;
            this.columnFunctionUsage.HeaderText = "Partition";
            this.columnFunctionUsage.Name = "columnFunctionUsage";
            this.columnFunctionUsage.Width = 51;
            // 
            // checkBoxRank
            // 
            this.checkBoxRank.AutoSize = true;
            this.checkBoxRank.Location = new System.Drawing.Point(18, 28);
            this.checkBoxRank.Name = "checkBoxRank";
            this.checkBoxRank.Size = new System.Drawing.Size(52, 17);
            this.checkBoxRank.TabIndex = 1;
            this.checkBoxRank.Tag = "Rank";
            this.checkBoxRank.Text = "Rank";
            this.checkBoxRank.UseVisualStyleBackColor = true;
            this.checkBoxRank.CheckedChanged += new System.EventHandler(this.CheckBoxCheckedChanged);
            // 
            // checkBoxDenseRank
            // 
            this.checkBoxDenseRank.AutoSize = true;
            this.checkBoxDenseRank.Location = new System.Drawing.Point(18, 54);
            this.checkBoxDenseRank.Name = "checkBoxDenseRank";
            this.checkBoxDenseRank.Size = new System.Drawing.Size(86, 17);
            this.checkBoxDenseRank.TabIndex = 2;
            this.checkBoxDenseRank.Tag = "DenseRank";
            this.checkBoxDenseRank.Text = "Dense Rank";
            this.checkBoxDenseRank.UseVisualStyleBackColor = true;
            this.checkBoxDenseRank.CheckedChanged += new System.EventHandler(this.CheckBoxCheckedChanged);
            // 
            // checkBoxRowNumber
            // 
            this.checkBoxRowNumber.AutoSize = true;
            this.checkBoxRowNumber.Location = new System.Drawing.Point(18, 82);
            this.checkBoxRowNumber.Name = "checkBoxRowNumber";
            this.checkBoxRowNumber.Size = new System.Drawing.Size(88, 17);
            this.checkBoxRowNumber.TabIndex = 3;
            this.checkBoxRowNumber.Tag = "RowNumber";
            this.checkBoxRowNumber.Text = "Row Number";
            this.checkBoxRowNumber.UseVisualStyleBackColor = true;
            this.checkBoxRowNumber.CheckedChanged += new System.EventHandler(this.CheckBoxCheckedChanged);
            // 
            // textBoxRank
            // 
            this.textBoxRank.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.textBoxRank.Enabled = false;
            this.textBoxRank.Location = new System.Drawing.Point(108, 28);
            this.textBoxRank.Name = "textBoxRank";
            this.textBoxRank.Size = new System.Drawing.Size(316, 20);
            this.textBoxRank.TabIndex = 4;
            this.textBoxRank.Validating += new System.ComponentModel.CancelEventHandler(this.TextBoxValidating);
            // 
            // textBoxDenseRank
            // 
            this.textBoxDenseRank.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.textBoxDenseRank.Enabled = false;
            this.textBoxDenseRank.Location = new System.Drawing.Point(108, 54);
            this.textBoxDenseRank.Name = "textBoxDenseRank";
            this.textBoxDenseRank.Size = new System.Drawing.Size(316, 20);
            this.textBoxDenseRank.TabIndex = 5;
            this.textBoxDenseRank.Validating += new System.ComponentModel.CancelEventHandler(this.TextBoxValidating);
            // 
            // textBoxRowNumber
            // 
            this.textBoxRowNumber.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.textBoxRowNumber.Enabled = false;
            this.textBoxRowNumber.Location = new System.Drawing.Point(108, 82);
            this.textBoxRowNumber.Name = "textBoxRowNumber";
            this.textBoxRowNumber.Size = new System.Drawing.Size(316, 20);
            this.textBoxRowNumber.TabIndex = 6;
            this.textBoxRowNumber.Validating += new System.ComponentModel.CancelEventHandler(this.TextBoxValidating);
            // 
            // groupBoxOutputColumns
            // 
            this.groupBoxOutputColumns.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.groupBoxOutputColumns.Controls.Add(this.checkBoxRank);
            this.groupBoxOutputColumns.Controls.Add(this.textBoxRowNumber);
            this.groupBoxOutputColumns.Controls.Add(this.checkBoxDenseRank);
            this.groupBoxOutputColumns.Controls.Add(this.textBoxDenseRank);
            this.groupBoxOutputColumns.Controls.Add(this.checkBoxRowNumber);
            this.groupBoxOutputColumns.Controls.Add(this.textBoxRank);
            this.groupBoxOutputColumns.Location = new System.Drawing.Point(15, 246);
            this.groupBoxOutputColumns.Name = "groupBoxOutputColumns";
            this.groupBoxOutputColumns.Size = new System.Drawing.Size(446, 122);
            this.groupBoxOutputColumns.TabIndex = 7;
            this.groupBoxOutputColumns.TabStop = false;
            this.groupBoxOutputColumns.Text = "Output Columns";
            // 
            // labelDescription
            // 
            this.labelDescription.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.labelDescription.Location = new System.Drawing.Point(15, 9);
            this.labelDescription.Name = "labelDescription";
            this.labelDescription.Size = new System.Drawing.Size(446, 43);
            this.labelDescription.TabIndex = 8;
            // 
            // groupBoxInputColumns
            // 
            this.groupBoxInputColumns.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.groupBoxInputColumns.Controls.Add(this.dataGridViewColumns);
            this.groupBoxInputColumns.Location = new System.Drawing.Point(15, 59);
            this.groupBoxInputColumns.Name = "groupBoxInputColumns";
            this.groupBoxInputColumns.Size = new System.Drawing.Size(446, 177);
            this.groupBoxInputColumns.TabIndex = 9;
            this.groupBoxInputColumns.TabStop = false;
            this.groupBoxInputColumns.Text = "Sorted Input Columns";
            // 
            // buttonOK
            // 
            this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.buttonOK.DialogResult = System.Windows.Forms.DialogResult.OK;
            this.buttonOK.Location = new System.Drawing.Point(305, 387);
            this.buttonOK.Name = "buttonOK";
            this.buttonOK.Size = new System.Drawing.Size(74, 24);
            this.buttonOK.TabIndex = 10;
            this.buttonOK.Text = "&OK";
            this.buttonOK.UseVisualStyleBackColor = true;
            // 
            // buttonCancel
            // 
            this.buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
            this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.No;
            this.buttonCancel.Location = new System.Drawing.Point(386, 387);
            this.buttonCancel.Name = "buttonCancel";
            this.buttonCancel.Size = new System.Drawing.Size(74, 24);
            this.buttonCancel.TabIndex = 11;
            this.buttonCancel.Text = "&Cancel";
            this.buttonCancel.UseVisualStyleBackColor = true;
            // 
            // RankTransformUIForm
            // 
            this.AcceptButton = this.buttonOK;
            this.CancelButton = this.buttonCancel;
            this.ClientSize = new System.Drawing.Size(479, 422);
            this.Controls.Add(this.buttonCancel);
            this.Controls.Add(this.buttonOK);
            this.Controls.Add(this.groupBoxInputColumns);
            this.Controls.Add(this.labelDescription);
            this.Controls.Add(this.groupBoxOutputColumns);
            this.MinimizeBox = false;
            this.Name = "RankTransformUIForm";
            this.ShowInTaskbar = false;
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
            this.Text = "Rank Transform Editor";
            ((System.ComponentModel.ISupportInitialize)(this.dataGridViewColumns)).EndInit();
            this.groupBoxOutputColumns.ResumeLayout(false);
            this.groupBoxOutputColumns.PerformLayout();
            this.groupBoxInputColumns.ResumeLayout(false);
            this.ResumeLayout(false);

        }

        private void OnColumnSelection(int lineageId, bool selected, out bool cancel)
        {
            cancel = true;
            try
            {
                this._errorCollectionService.ClearErrors();
                IDTSVirtualInputColumn100 virtualInputColumnByLineageID = this._virtualInput.VirtualInputColumnCollection.GetVirtualInputColumnByLineageID(lineageId);
                if (selected)
                {
                    this._designTimeComponent.SetUsageType(this._input.ID, this._virtualInput, virtualInputColumnByLineageID.LineageID, 0);
                }
                else
                {
                    this._designTimeComponent.SetUsageType(this._input.ID, this._virtualInput, virtualInputColumnByLineageID.LineageID, (DTSUsageType) 2);
                }
                DataGridViewCheckBoxCell cell = this.dataGridViewColumns.CurrentRow.Cells[3] as DataGridViewCheckBoxCell;
                cell.ReadOnly = !selected;
                cell.Value = false;
                cell.Style.ForeColor = Color.Indigo;
                cancel = false;
            }
            catch (Exception exception)
            {
                string errorMessage = this._errorCollectionService.GetErrorMessage();
                if ((errorMessage == null) || (errorMessage.Length == 0))
                {
                    //errorMessage = Resources.ErrorColumnSelection;
                }
                ExceptionMessageBox box = new ExceptionMessageBox(errorMessage, this.Text);
                box.InnerException = exception;
                box.Show(this);
            }
        }

        private void OnPartitionSelection(int lineageId, bool selected, out bool cancel)
        {
            cancel = true;
            try
            {
                this._errorCollectionService.ClearErrors();
                this._designTimeComponent.SetInputColumnProperty(this._input.ID, this._input.InputColumnCollection.GetInputColumnByLineageID(lineageId).ID, "IsPartitionColumn", selected);
                cancel = false;
            }
            catch (Exception exception)
            {
                string errorMessage = this._errorCollectionService.GetErrorMessage();
                if ((errorMessage == null) || (errorMessage.Length == 0))
                {
                    //errorMessage = Resources.ErrorColumnSelection;
                }
                ExceptionMessageBox box = new ExceptionMessageBox(errorMessage, this.Text);
                box.InnerException = exception;
                box.Show(this);
            }
        }

        private void SetInputVirtualInputColumns()
        {
            this._virtualInput = this._input.GetVirtualInput();
            var virtualInputCols = this._virtualInput.VirtualInputColumnCollection;
            var inputCols = this._input.InputColumnCollection;
            var numVirtualInputCols = virtualInputCols.Count;
            for (var i = 0; i < numVirtualInputCols; i++)
            {
                var currentVirtualInputCol = virtualInputCols[i];
                if (currentVirtualInputCol.SortKeyPosition > 0)
                {
                    int num3;
                    if ((currentVirtualInputCol.UsageType == null) || (currentVirtualInputCol.UsageType == (DTSUsageType) 1))
                    {
                        //What is the custom property that they're after here???? Is is IsPartition? Should it be named explicitly?
                        var flag = Convert.ToBoolean(inputCols.GetInputColumnByLineageID(currentVirtualInputCol.LineageID)
                                                        .CustomPropertyCollection[0].Value);
                        num3 = this.dataGridViewColumns.Rows.Add(
                            new object[] 
                            { 
                                CheckState.Checked, currentVirtualInputCol.SortKeyPosition, " " + currentVirtualInputCol.Name, flag 
                            });
                    }
                    else
                    {
                        num3 = this.dataGridViewColumns.Rows.Add(
                            new object[]
                                {
                                    CheckState.Unchecked, currentVirtualInputCol.SortKeyPosition, " " + currentVirtualInputCol.Name, false
                                });
                    }
                    this.dataGridViewColumns.Rows[num3].Tag = currentVirtualInputCol.LineageID;
                    var cell = (DataGridViewCheckBoxCell)this.dataGridViewColumns.Rows[num3].Cells[0];
                    cell.ThreeState = false;
                }
            }
        }

        private void TextBoxValidating(object sender, CancelEventArgs e)
        {
            string text = null;
            var box = sender as TextBox;
            try
            {
                this._errorCollectionService.ClearErrors();
                var outputColumnByLineageID = this._output.OutputColumnCollection.GetOutputColumnByLineageID(Convert.ToInt32(box.Tag));
                text = box.Text;
                outputColumnByLineageID.Name = box.Text;
            }
            catch (Exception exception)
            {
                if ((text != null) && (text.Length > 0))
                {
                    box.Text = text;
                }
                string errorMessage = this._errorCollectionService.GetErrorMessage();
                if ((errorMessage == null) || (errorMessage.Length == 0))
                {
                    //errorMessage = Resources.ErrorColumnSelection;
                }
                var box2 = new ExceptionMessageBox(errorMessage, this.Text);
                box2.InnerException = exception;
                box2.Show(this);
            }
        }
    }
}

